<?php
#
# dmBridge: a data access framework for CONTENTdm(R)
#
# Copyright © 2009, 2010, 2011 Board of Regents of the Nevada System of Higher
# Education, on behalf of the University of Nevada, Las Vegas
#

/**
 * Manages all configuration operations involving the config.ini file.
 *
 * @author Alex Dolski <alex.dolski@unlv.edu>
 * @license http://www.opensource.org/licenses/mit-license.php
 */
class DMConfigIni {

	/**
	 * @var array instances Array of Singleton instances, one per file
	 */
	private static $instances = array();

	/** @var array config_ini_data */
	private $config_ini_data;
	/** @var string config_ini_pathname */
	private $config_ini_pathname;

	/**
	 * @return string
	 */
	private static function getDefaultIniPathname() {
		return dirname(__FILE__) . "/../../config.ini";
	}

	/**
	 * @param string ini_file_pathname
	 * @return DMConfigIni
	 */
	public static function getInstance($ini_file_pathname = null) {
		if (!$ini_file_pathname) {
			$ini_file_pathname = self::getDefaultIniPathname();
		}
		if (!array_key_exists($ini_file_pathname, self::$instances)) {
			self::$instances[$ini_file_pathname] = new DMConfigIni(
					$ini_file_pathname);
		}
		return self::$instances[$ini_file_pathname];
	}

	/**
	 * @param DMConfigIni instance
	 * @return void
	 */
	public static function destroyInstance(DMConfigIni $instance) {
		foreach (self::$instances as $pathname => $inst) {
			if ($inst == $instance) {
				unset(self::$instances[$pathname]);
				break;
			}
		}
	}

	/**
	 * @param string ini_file_pathname
	 */
	protected function __construct($ini_file_pathname) {
		$this->config_ini_pathname = $ini_file_pathname;
	}

	public function __clone() {}
	public function __wakeup() {}

	/**
	 * @param string key
	 * @return string The boolean value corresponding to key $key, or null if
	 * not found.
	 */
	public function getBoolean($key) {
		if (!$this->config_ini_data) {
			$this->initConfigIniData();
		}
		if (array_key_exists($key, $this->config_ini_data)) {
			if (in_array($this->config_ini_data[$key], array("1", "true"))) {
				return true;
			} else if (in_array($this->config_ini_data[$key], array("0", "false"))) {
				return false;
			}
		}
		return null;
	}

	/**
	 * Sets or overrides a config setting.
	 *
	 * @param string key
	 * @param boolean value
	 */
	public function setBoolean($key, $value) {
		if (!$this->config_ini_data) {
			$this->initConfigIniData();
		}
		$this->config_ini_data[$key] = $value ? "true" : "false";
	}

	/**
	 * Unsets a config setting.
	 *
	 * @param string key
	 */
	public function unsetKey($key) {
		if (!$this->config_ini_data) {
			$this->initConfigIniData();
		}
		if (array_key_exists($key, $this->config_ini_data)) {
			unset($this->config_ini_data[$key]);
		}
	}

	/**
	 * @param string key
	 * @param string default_value Value to return if there is no value
	 * corresponding to $key
	 * @return string The string corresponding to key $key, or null if not
	 * found.
	 */
	public function getString($key, $default_value = null) {
		if (!$this->config_ini_data) {
			$this->initConfigIniData();
		}
		return array_key_exists($key, $this->config_ini_data)
				? $this->config_ini_data[$key] : $default_value;
	}

	/**
	 * Sets or overrides a config setting.
	 *
	 * @param string key
	 * @param string value
	 */
	public function setString($key, $value) {
		if (!$this->config_ini_data) {
			$this->initConfigIniData();
		}
		$this->config_ini_data[$key] = $value;
	}

	private function initConfigIniData() {
		if (!$this->config_ini_data) {
			$this->config_ini_data = parse_ini_file($this->config_ini_pathname);
		}
		return $this->config_ini_data;
	}

}
